---
title: Carousel
description: "`Carousel` is a component that displays multiple elements like a slideshow."
storybook: components-carousel--basic
source: components/carousel
style: components/carousel/carousel.style.ts
---

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item key={index} index={index}>
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

## Usage

:::code-group

```tsx [package]
import { Carousel } from "@yamada-ui/react"
```

```tsx [alias]
import { Carousel } from "@/components/ui"
```

```tsx [monorepo]
import { Carousel } from "@workspaces/ui"
```

:::

```tsx
<Carousel.Root>
  <Carousel.List>
    <Carousel.Item />
  </Carousel.List>
  <Carousel.PrevTrigger />
  <Carousel.NextTrigger />
  <Carousel.Indicators>
    <Carousel.Indicator />
  </Carousel.Indicators>
</Carousel.Root>
```

:::note
`Carousel` internally uses [embla-carousel-react](https://www.embla-carousel.com/).
:::

### Change Size

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <VStack>
    <For each={["sm", "md", "lg"]}>
      {(size, key) => (
        <Carousel.Root key={key} size={size}>
          <Carousel.List>
            {sources.map((src, index) => (
              <Carousel.Item key={index} index={index}>
                <Image
                  src={src}
                  alt="スタジオジブリ作品静止画"
                  boxSize="full"
                  objectFit="cover"
                />
              </Carousel.Item>
            ))}
          </Carousel.List>

          <Carousel.PrevTrigger />
          <Carousel.NextTrigger />

          <Carousel.Indicators />
        </Carousel.Root>
      )}
    </For>
  </VStack>
)
```

### Change Color Scheme

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <VStack>
    <For each={["success", "warning"]}>
      {(colorScheme, key) => (
        <Carousel.Root key={key} colorScheme={colorScheme}>
          <Carousel.List>
            {sources.map((src, index) => (
              <Carousel.Item key={index} index={index}>
                <Image
                  src={src}
                  alt="スタジオジブリ作品静止画"
                  boxSize="full"
                  objectFit="cover"
                />
              </Carousel.Item>
            ))}
          </Carousel.List>

          <Carousel.PrevTrigger />
          <Carousel.NextTrigger />

          <Carousel.Indicators />
        </Carousel.Root>
      )}
    </For>
  </VStack>
)
```

### Change Direction

To change the direction, set `orientation` to `"horizontal"` or `"vertical"`. By default, `"horizontal"` is set.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <VStack>
    <For each={["horizontal", "vertical"]}>
      {(orientation, key) => (
        <Carousel.Root key={key} orientation={orientation}>
          <Carousel.List>
            {sources.map((src, index) => (
              <Carousel.Item key={index} index={index}>
                <Image
                  src={src}
                  alt="スタジオジブリ作品静止画"
                  boxSize="full"
                  objectFit="cover"
                />
              </Carousel.Item>
            ))}
          </Carousel.List>

          <Carousel.PrevTrigger />
          <Carousel.NextTrigger />

          <Carousel.Indicators />
        </Carousel.Root>
      )}
    </For>
  </VStack>
)
```

### Select the default slide

To select the default slide, set `defaultIndex` to the `index`.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root defaultIndex={1}>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item key={index} index={index}>
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Adjust the space between slides

To adjust the space between slides, set `gap` to a string or a number. By default, `1rem` is set.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root gap="0">
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item key={index} index={index}>
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Change the duration of slide transition

To change the duration of slide transition, set `duration` to a number. By default, `25` is set.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root duration={60}>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item key={index} index={index}>
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Change the size of the slides

To change the size of the slides, set `slideSize` to a string or a number. By default, `100`% is set.

If you want to change the size of individual slides, set the value to `slideSize` of `Carousel.Item`.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root slideSize="50%">
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item
          key={index}
          index={index}
          slideSize={index === 1 ? "100%" : undefined}
        >
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Change the alignment of the slides

To change the alignment of the slides, set `align` to `"start"`, `"center"`, `"end"`, or a number. By default, `"center"` is set.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <VStack>
    <For each={["center", "start", "end"]}>
      {(align, key) => (
        <Carousel.Root key={key} slideSize="50%" align={align}>
          <Carousel.List>
            {sources.map((src, index) => (
              <Carousel.Item key={index} index={index}>
                <Image
                  src={src}
                  alt="スタジオジブリ作品静止画"
                  boxSize="full"
                  objectFit="cover"
                />
              </Carousel.Item>
            ))}
          </Carousel.List>

          <Carousel.PrevTrigger />
          <Carousel.NextTrigger />

          <Carousel.Indicators />
        </Carousel.Root>
      )}
    </For>
  </VStack>
)
```

### Change the number of slides to scroll

To change the number of slides to scroll, set `slidesToScroll` to a number. By default, `1` is set.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root slideSize={`${100 / 3}%`} slidesToScroll={3}>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item key={index} index={index}>
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Use autoplay

To use autoplay, set `autoplay` to `true`.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root autoplay>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item
          key={index}
          index={index}
          slideSize={index === 1 ? "100%" : undefined}
        >
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Change the autoplay interval

To change the autoplay interval, set `delay` to a number (milliseconds). By default, `4000` is set.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root autoplay delay={1000}>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item
          key={index}
          index={index}
          slideSize={index === 1 ? "100%" : undefined}
        >
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Do not stop autoplay on mouse enter

By default, autoplay stops when the element is hovered over. To prevent this, set `stopMouseEnterAutoplay` to `false`.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root autoplay stopMouseEnterAutoplay={false}>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item
          key={index}
          index={index}
          slideSize={index === 1 ? "100%" : undefined}
        >
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Use Drag-Free

To use drag-free, set `dragFree` to `true`.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root dragFree>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item
          key={index}
          index={index}
          slideSize={index === 1 ? "100%" : undefined}
        >
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Disable looping

To disable looping, set `loop` to `false`.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root loop={false}>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item
          key={index}
          index={index}
          slideSize={index === 1 ? "100%" : undefined}
        >
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Disable dragging

To disable dragging, set `draggable` to `false`.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root draggable={false}>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item
          key={index}
          index={index}
          slideSize={index === 1 ? "100%" : undefined}
        >
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Customize control buttons

To customize control buttons, set props to `Carousel.PrevTrigger` or `Carousel.NextTrigger`.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item
          key={index}
          index={index}
          slideSize={index === 1 ? "100%" : undefined}
        >
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger
      bottom="4"
      icon={<ArrowLeftIcon />}
      top="unset"
      transform="unset"
    />
    <Carousel.NextTrigger
      bottom="4"
      icon={<ArrowRightIcon />}
      top="unset"
      transform="unset"
    />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Customize indicators

To customize indicators, set props to `Carousel.Indicators`.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root>
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item
          key={index}
          index={index}
          slideSize={index === 1 ? "100%" : undefined}
        >
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators
      h="6"
      render={({ selected }) => (
        <Center as="button" cursor="pointer">
          <CircleIcon
            data-selected={dataAttr(selected)}
            color="transparent"
            fill="colorScheme.solid/40"
            fontSize="2xl"
            _selected={{
              fill: "colorScheme.solid",
            }}
            _hover={{
              _notSelected: {
                fill: "colorScheme.solid/70",
              },
            }}
          />
        </Center>
      )}
    />
  </Carousel.Root>
)
```

### Handle Events

If you want to handle events such as user drag, use `watchDrag`.

```tsx preview functional
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <Carousel.Root
    watchDrag={(methods, ev) => {
      console.log("drag", methods, ev)
      return true
    }}
    watchResize={(methods, entries) => {
      console.log("resized", methods, entries)
      return true
    }}
    watchSlides={(methods, mutations) => {
      console.log("slides updated", methods, mutations)
      return true
    }}
  >
    <Carousel.List>
      {sources.map((src, index) => (
        <Carousel.Item key={index} index={index}>
          <Image
            src={src}
            alt="スタジオジブリ作品静止画"
            boxSize="full"
            objectFit="cover"
          />
        </Carousel.Item>
      ))}
    </Carousel.List>

    <Carousel.PrevTrigger />
    <Carousel.NextTrigger />

    <Carousel.Indicators />
  </Carousel.Root>
)
```

### Control

```tsx preview functional client
const controlRef = useRef<Carousel.Control>(null)
const [index, setIndex] = useState(0)
const [sources, setSources] = useState([
  "https://www.ghibli.jp/gallery/baron001.jpg",
  "https://www.ghibli.jp/gallery/baron002.jpg",
  "https://www.ghibli.jp/gallery/baron003.jpg",
  "https://www.ghibli.jp/gallery/baron004.jpg",
  "https://www.ghibli.jp/gallery/baron005.jpg",
])

return (
  <VStack>
    <Carousel.Root controlRef={controlRef} index={index} onChange={setIndex}>
      <Carousel.List>
        {sources.map((src, index) => (
          <Carousel.Item key={index} index={index}>
            <Image
              src={src}
              alt="スタジオジブリ作品静止画"
              boxSize="full"
              objectFit="cover"
            />
          </Carousel.Item>
        ))}
      </Carousel.List>

      <Carousel.PrevTrigger />
      <Carousel.NextTrigger />

      <Carousel.Indicators />
    </Carousel.Root>

    <ButtonGroup.Root>
      <ButtonGroup.Item
        disabled={sources.length === 50}
        onClick={() => {
          const num = (sources.length + 1).toString().padStart(2, "0")
          const nextSources = [
            ...sources,
            `https://www.ghibli.jp/gallery/baron0${num}.jpg`,
          ]
          setSources(nextSources)
          setIndex(nextSources.length - 1)
        }}
      >
        Add
      </ButtonGroup.Item>
      <ButtonGroup.Item
        disabled={sources.length === 1}
        onClick={() => {
          if (index === sources.length - 1) setIndex((prev) => prev - 1)
          setSources(sources.slice(0, -1))
        }}
      >
        Remove
      </ButtonGroup.Item>
    </ButtonGroup.Root>

    <VStack gap="sm">
      <Text>State</Text>
      <ButtonGroup.Root>
        <ButtonGroup.Item onClick={() => setIndex(0)}>Home</ButtonGroup.Item>
        <ButtonGroup.Item
          onClick={() =>
            setIndex((prev) => (prev === 0 ? sources.length - 1 : prev - 1))
          }
        >
          Prev
        </ButtonGroup.Item>
        <ButtonGroup.Item
          onClick={() =>
            setIndex((prev) => (prev === sources.length - 1 ? 0 : prev + 1))
          }
        >
          Next
        </ButtonGroup.Item>
        <ButtonGroup.Item onClick={() => setIndex(sources.length - 1)}>
          End
        </ButtonGroup.Item>
      </ButtonGroup.Root>
    </VStack>

    <VStack gap="sm">
      <Text>Ref</Text>
      <ButtonGroup.Root>
        <ButtonGroup.Item onClick={() => controlRef.current?.scrollTo(0)}>
          Home
        </ButtonGroup.Item>
        <ButtonGroup.Item onClick={() => controlRef.current?.scrollPrev()}>
          Prev
        </ButtonGroup.Item>
        <ButtonGroup.Item onClick={() => controlRef.current?.scrollNext()}>
          Next
        </ButtonGroup.Item>
        <ButtonGroup.Item
          onClick={() => controlRef.current?.scrollTo(sources.length - 1)}
        >
          End
        </ButtonGroup.Item>
      </ButtonGroup.Root>
    </VStack>
  </VStack>
)
```

```tsx preview functional client
const [index, setIndex] = useState(0)
const sources = useMemo(
  () =>
    Array.from(
      {
        length: 50,
      },
      (_, index) => {
        const num = (index + 1).toString().padStart(2, "0")
        return `https://www.ghibli.jp/gallery/baron0${num}.jpg`
      },
    ),
  [],
)

return (
  <VStack>
    <Carousel.Root index={index} onChange={setIndex}>
      <Carousel.List>
        {sources.map((src, index) => (
          <Carousel.Item key={index} index={index}>
            <Image
              src={src}
              alt="スタジオジブリ作品静止画"
              boxSize="full"
              objectFit="cover"
            />
          </Carousel.Item>
        ))}
      </Carousel.List>
    </Carousel.Root>

    <Carousel.Root
      containScroll="keepSnaps"
      dragFree
      h="5xs"
      index={index}
      slideSize="20%"
    >
      <Carousel.List>
        {sources.map((src, index) => (
          <Carousel.Item
            key={index}
            cursor="pointer"
            index={index}
            opacity="0.4"
            _selected={{
              opacity: 1,
            }}
            onClick={() => setIndex(index)}
          >
            <Image
              src={src}
              alt="スタジオジブリ作品静止画"
              boxSize="full"
              objectFit="cover"
            />
          </Carousel.Item>
        ))}
      </Carousel.List>
    </Carousel.Root>
  </VStack>
)
```

You can access the current scroll amount using `onScrollProgress`.

```tsx preview functional client
const [progress, setProgress] = useState(0)
const sources = useMemo(
  () => [
    "https://www.ghibli.jp/gallery/chihiro015.jpg",
    "https://www.ghibli.jp/gallery/howl049.jpg",
    "https://www.ghibli.jp/gallery/totoro036.jpg",
    "https://www.ghibli.jp/gallery/mononoke033.jpg",
    "https://www.ghibli.jp/gallery/laputa047.jpg",
    "https://www.ghibli.jp/gallery/porco025.jpg",
  ],
  [],
)

return (
  <VStack>
    <Carousel.Root dragFree loop={false} onScrollProgress={setProgress}>
      <Carousel.List>
        {sources.map((src, index) => (
          <Carousel.Item key={index} index={index}>
            <Image
              src={src}
              alt="スタジオジブリ作品静止画"
              boxSize="full"
              objectFit="cover"
            />
          </Carousel.Item>
        ))}
      </Carousel.List>

      <Carousel.PrevTrigger />
      <Carousel.NextTrigger />

      <Carousel.Indicators />
    </Carousel.Root>

    <Progress value={progress} />
  </VStack>
)
```

## Props

<PropsTable name="carousel" />

## Accessibility

Currently, this section is being updated due to the migration of v2.
